Skip to content

feat: newer messages thread first#38

Open
jugarpeupv wants to merge 26 commits intoyousefakbar:mainfrom
jugarpeupv:feature/newest_messages_thread_first
Open

feat: newer messages thread first#38
jugarpeupv wants to merge 26 commits intoyousefakbar:mainfrom
jugarpeupv:feature/newest_messages_thread_first

Conversation

@jugarpeupv
Copy link
Copy Markdown
Contributor

@jugarpeupv jugarpeupv commented Feb 18, 2026

@yousefakbar what do you think about this feature?

jugarpeupv and others added 26 commits January 19, 2026 15:13
Detects calendar files by MIME type or extension and attempts to render them
using the external script `render-calendar-attachment.py`. If the script is not
available, a message is shown with a link to download it. This improves the
handling of .ics and similar calendar attachments in the default view handler.
Formatter fixed mixed indentation (tabs vs spaces) and inconsistent
spacing throughout the file to match project style guidelines.
Added documentation for the new optional email address parameter in
the :Inbox command, which allows filtering inbox by recipient address
with autocomplete support.

Updated CHANGELOG.md, README.md, and doc/notmuch.txt to reflect the
new functionality.
Replace brittle regex-based text parsing with structured JSON parsing
for displaying email threads. This provides more reliable MIME handling
and enables new features.

Changes:
- Add thread.lua module with JSON-based thread processing
- Replace `notmuch show | col` with `notmuch show --format=json`
- Handle complex MIME structures (multipart/mixed, multipart/alternative)
- Concatenate multiple inline text parts (body, signatures, footers)
- Show MIME markers for attachments and HTML content

New features:
- Per-message tag display in thread headers
- Attachment count indicator (📎) in message headers
- Proper handling of text/plain attachments vs inline content

Deprecates util.process_msgs_in_thread() in favor of thread.show_thread()
Add support for rendering HTML email bodies in thread view using w3m.
This is useful for multipart/alternative emails where HTML content is
often richer than the plain text alternative.

- Add `render_html_body` config option (default: false)
- Add `render_html()` function with w3m integration
- Graceful fallback when w3m is not installed or fails
- Fetch HTML content from notmuch with `--include-html` flag
- Add module-level documentation to thread.lua
Add `vim.b.notmuch_thread` buffer variable containing thread-level
metadata for extensibility (statusline integration, custom scripts).

Exported fields:
- id: Thread ID for notmuch queries
- subject: Thread subject from root message
- date_relative: Root message date
- message_count: Total messages in thread
- tags: Union of all message tags (sorted)
- authors: Unique participants (full From header, deduplicated)

Implementation:
- Accumulate metadata during `build_message_lines()` tree traversal
- Return (lines, metadata) tuple from `show_thread()`
- Caller sets buffer variable after creating buffer

This is the first of several buffer variables that will enable
O(1) message lookup and rich statusline integration.
Add `vim.b.notmuch_messages` buffer variable containing an array of
message objects for cursor-to-message lookup and statusline integration.

Each message entry includes:
- id: Message-ID for notmuch queries
- start_line, end_line, fold_line: Line ranges for cursor mapping
- depth: Reply depth in thread
- from, subject, date_relative: Display fields
- tags: Per-message tags array
- attachment_count: Number of attachments

Implementation:
- Track line positions during `build_message_lines()` traversal
- Restructure metadata return as { thread, messages } object
- Caller sets both `vim.b.notmuch_thread` and `vim.b.notmuch_messages`

This enables O(m) message lookup by cursor position, replacing the
O(n) buffer-scanning approach in `util.find_cursor_msg_id()`.
Add `vim.b.notmuch_current` and `vim.b.notmuch_status` buffer variables
that automatically update as the cursor moves through the thread.

`vim.b.notmuch_current` contains:
- All fields from the message at cursor (id, from, tags, etc.)
- index: 1-based position in thread
- total: total message count

`vim.b.notmuch_status` contains a pre-formatted string for statusline:
- Format: "2/7 Alice Smith" or "2/7 Alice Smith 📎2" with attachments

Implementation:
- Add get_message_at_line() for O(m) cursor-to-message lookup
- Add update_current_message() to refresh buffer variables
- Add setup_cursor_tracking() to create buffer-local CursorMoved autocmd
- Fast path optimization skips update if cursor still in same message
Simplifies operations (8 instances) where ID was being fetching the
current (cursor) message ID by scanning lines backwards.

Instead, we simply reference the `id` field in the buffer-local variable
`vim.b.notmuch_current`, which is updated via autocmd on every cursor
move event.
…mprovements

Adds detail on new thread metadata buffer variables for statusline
integration and clarifies the refactored message ID lookup pattern.
Previously, show_thread() only processed json[1][1], assuming a single
root node. Threads with multiple depth-0 messages (e.g., orphaned
replies, merged threads) were truncated to only the first message.

Now iterates over all nodes in json[1] to display the complete thread.
When cursor is at the top of the buffer or in a gap between messages,
update_current_message() now falls back to finding the first message
whose start_line is after the cursor position.

Previously it would clear notmuch_current and notmuch_status, leaving
the status bar empty despite messages being present in the thread.
- README: Add w3m as optional dependency, render_html_body config
  option, and new "Statusline Integration" section with lualine example
- Help: Add render_html_body option, w3m dependency, comprehensive
  buffer-local variables reference (:help notmuch-buffer-variables), and
  thread.lua module description
- CHANGELOG: Note documentation additions
Add changelog entries describing the completion of the major refactoring
that removed all Vimscript dependencies and migrated to pure Lua
implementation with improved completion filtering.
Remove references to deleted plugin/notmuch.vim and autoload/notmuch.vim
files. Reflect command definitions now in init.lua using
vim.api.nvim_create_user_command.

Update doc/notmuch.txt COMPLETION section to reference the new
completion.lua Lua module instead of the old autoload function. Add
completion.lua module documentation to the LUA MODULES section
describing its purpose and exported functions.
Update TagAdd/TagRm/TagToggle commands in ftplugin files to use the new
notmuch.completion.comp_tags Lua function instead of the deprecated
notmuch#CompTags Vimscript autoload function. Use customlist completion
type for proper handling of Lua table returns.
Introduce a `message_order` config option to control the order of messages
displayed in the thread view. Users can choose between "newest-first" and
"oldest-first" to suit their preference. When set to "newest-first", the
thread view flattens and sorts messages by timestamp in descending order.
Default behavior maintains the original hierarchical order.
@jugarpeupv jugarpeupv changed the title Feature/newest messages thread first feat: newer messages thread first Feb 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants